//
// --------------------------------------------------------------------------
//  Gurux Ltd
// 
//
//
// Filename:        $HeadURL$
//
// Version:         $Revision$,
//                  $Date$
//                  $Author$
//
// Copyright (c) Gurux Ltd
//
//---------------------------------------------------------------------------
//
//  DESCRIPTION
//
// This file is a part of Gurux Device Framework.
//
// Gurux Device Framework is Open Source software; you can redistribute it
// and/or modify it under the terms of the GNU General Public License 
// as published by the Free Software Foundation; version 2 of the License.
// Gurux Device Framework is distributed in the hope that it will be useful,
// but WITHOUT ANY WARRANTY; without even the implied warranty of 
// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. 
// See the GNU General Public License for more details.
//
// More information of Gurux products: https://www.gurux.org
//
// This code is licensed under the GNU General Public License v2. 
// Full text may be retrieved at http://www.gnu.org/licenses/gpl-2.0.txt
//---------------------------------------------------------------------------

package gurux.dlms.objects;

import java.security.InvalidAlgorithmParameterException;
import java.security.InvalidKeyException;
import java.security.NoSuchAlgorithmException;
import java.util.ArrayList;
import java.util.List;

import javax.crypto.BadPaddingException;
import javax.crypto.IllegalBlockSizeException;
import javax.crypto.NoSuchPaddingException;
import javax.xml.stream.XMLStreamException;

import gurux.dlms.GXByteBuffer;
import gurux.dlms.GXDLMSClient;
import gurux.dlms.GXDLMSSettings;
import gurux.dlms.ValueEventArgs;
import gurux.dlms.enums.DataType;
import gurux.dlms.enums.ErrorCode;
import gurux.dlms.enums.ObjectType;
import gurux.dlms.internal.GXCommon;

/**
 * Online help:<br>
 * https://www.gurux.fi/Gurux.DLMS.Objects.GXDLMSPrimeNbOfdmPlcMacNetworkAdministrationData
 */
public class GXDLMSPrimeNbOfdmPlcMacNetworkAdministrationData extends GXDLMSObject implements IGXDLMSBase {

	/**
	 * List of entries in multicast switching table.
	 */

	private GXMacMulticastEntry[] multicastEntries;
	/**
	 * Switch table.
	 */
	private short[] switchTable;

	/**
	 * List of entries in multicast switching table.
	 */
	private GXMacDirectTable[] directTable;
	/**
	 * List of available switches.
	 */
	private GXMacAvailableSwitch[] availableSwitches;
	/**
	 * List of PHY communication parameters.
	 */
	private GXMacPhyCommunication[] communications;

	/**
	 * Constructor.
	 */
	public GXDLMSPrimeNbOfdmPlcMacNetworkAdministrationData() {
		this("0.0.28.5.0.255", 0);
	}

	/**
	 * Constructor.
	 * 
	 * @param ln Logical Name of the object.
	 */
	public GXDLMSPrimeNbOfdmPlcMacNetworkAdministrationData(final String ln) {
		this(ln, 0);
	}

	/**
	 * Constructor.
	 * 
	 * @param ln Logical Name of the object.
	 * @param sn Short Name of the object.
	 */
	public GXDLMSPrimeNbOfdmPlcMacNetworkAdministrationData(final String ln, final int sn) {
		super(ObjectType.PRIME_NB_OFDM_PLC_MAC_NETWORK_ADMINISTRATION_DATA, ln, sn);
	}

	/**
	 * @return List of entries in multicast switching table.
	 */
	public final GXMacMulticastEntry[] getMulticastEntries() {
		return multicastEntries;
	}

	/**
	 * @param value List of entries in multicast switching table.
	 */
	public final void setMulticastEntries(final GXMacMulticastEntry[] value) {
		multicastEntries = value;
	}

	/**
	 * @return Switch table.
	 */
	public final short[] getSwitchTable() {
		return switchTable;
	}

	/**
	 * @param value Switch table.
	 */
	public final void setSwitchTable(final short[] value) {
		switchTable = value;
	}

	/**
	 * @return List of entries in multicast switching table.
	 */
	public final GXMacDirectTable[] getDirectTable() {
		return directTable;
	}

	/**
	 * @param value List of entries in multicast switching table.
	 */
	public final void setDirectTable(final GXMacDirectTable[] value) {
		directTable = value;
	}

	/**
	 * @return List of available switches.
	 */
	public final GXMacAvailableSwitch[] getAvailableSwitches() {
		return availableSwitches;
	}

	/**
	 * @param value List of available switches.
	 */
	public final void setAvailableSwitches(final GXMacAvailableSwitch[] value) {
		availableSwitches = value;
	}

	/**
	 * @return List of PHY communication parameters.
	 */
	public final GXMacPhyCommunication[] getCommunications() {
		return communications;
	}

	/**
	 * @param value List of PHY communication parameters.
	 */
	public final void setCommunications(final GXMacPhyCommunication[] value) {
		communications = value;
	}

	/**
	 * Reset the values.
	 * 
	 * @param client DLMS client.
	 * @return Action bytes.
	 * @throws NoSuchPaddingException             No such padding exception.
	 * @throws NoSuchAlgorithmException           No such algorithm exception.
	 * @throws InvalidAlgorithmParameterException Invalid algorithm parameter
	 *                                            exception.
	 * @throws InvalidKeyException                Invalid key exception.
	 * @throws BadPaddingException                Bad padding exception.
	 * @throws IllegalBlockSizeException          Illegal block size exception.
	 */
	public final byte[][] reset(final GXDLMSClient client) throws InvalidKeyException, NoSuchAlgorithmException,
			NoSuchPaddingException, InvalidAlgorithmParameterException, IllegalBlockSizeException, BadPaddingException {
		return client.method(this, 1, 0, DataType.INT8);
	}

	@Override
	public final Object[] getValues() {
		return new Object[] { getLogicalName(), multicastEntries, switchTable, directTable, availableSwitches,
				communications };
	}

	@Override
	public final byte[] invoke(final GXDLMSSettings settings, final ValueEventArgs e) {
		if (e.getIndex() == 1) {
			multicastEntries = null;
			switchTable = null;
			directTable = null;
			availableSwitches = null;
			communications = null;
		} else {
			e.setError(ErrorCode.READ_WRITE_DENIED);
		}
		return null;
	}

	/*
	 * Returns collection of attributes to read. If attribute is static and already
	 * read or device is returned HW error it is not returned.
	 */
	@Override
	public final int[] getAttributeIndexToRead(final boolean all) {
		java.util.ArrayList<Integer> attributes = new java.util.ArrayList<Integer>();
		// LN is static and read only once.
		if (all || getLogicalName() == null || getLogicalName().compareTo("") == 0) {
			attributes.add(1);
		}
		// MulticastEntries
		if (all || canRead(2)) {
			attributes.add(2);
		}
		// SwitchTable
		if (all || canRead(3)) {
			attributes.add(3);
		}
		// DirectTable
		if (all || canRead(4)) {
			attributes.add(4);
		}
		// AvailableSwitches
		if (all || canRead(5)) {
			attributes.add(5);
		}
		// Communications
		if (all || canRead(6)) {
			attributes.add(6);
		}
		return GXDLMSObjectHelpers.toIntArray(attributes);
	}

	/*
	 * Returns amount of attributes.
	 */
	@Override
	public final int getAttributeCount() {
		return 6;
	}

	/*
	 * Returns amount of methods.
	 */
	@Override
	public final int getMethodCount() {
		return 1;
	}

	@Override
	public final DataType getDataType(final int index) {
		switch (index) {
		case 1:
			return DataType.OCTET_STRING;
		case 2:
		case 3:
		case 4:
		case 5:
		case 6:
			return DataType.ARRAY;
		default:
			throw new IllegalArgumentException("getDataType failed. Invalid attribute index.");
		}
	}

	private byte[] getMulticastEntries(final GXDLMSSettings settings) {
		GXByteBuffer bb = new GXByteBuffer();
		bb.setUInt8(DataType.ARRAY.getValue());
		if (multicastEntries == null) {
			GXCommon.setObjectCount(0, bb);
		} else {
			GXCommon.setObjectCount(multicastEntries.length, bb);
			for (GXMacMulticastEntry it : multicastEntries) {
				bb.setUInt8((byte) DataType.STRUCTURE.getValue());
				bb.setUInt8(2);
				GXCommon.setData(settings, bb, DataType.INT8, it.getId());
				GXCommon.setData(settings, bb, DataType.INT16, it.getMembers());
			}
		}
		return bb.array();
	}

	private byte[] getSwitchTable(final GXDLMSSettings settings) {
		GXByteBuffer bb = new GXByteBuffer();
		bb.setUInt8(DataType.ARRAY.getValue());
		if (switchTable == null) {
			GXCommon.setObjectCount(0, bb);
		} else {
			GXCommon.setObjectCount(switchTable.length, bb);
			for (short it : switchTable) {
				GXCommon.setData(settings, bb, DataType.INT16, it);
			}
		}
		return bb.array();
	}

	private byte[] getDirectTable(final GXDLMSSettings settings) {
		GXByteBuffer bb = new GXByteBuffer();
		bb.setUInt8(DataType.ARRAY.getValue());
		if (directTable == null) {
			GXCommon.setObjectCount(0, bb);
		} else {
			GXCommon.setObjectCount(directTable.length, bb);
			for (GXMacDirectTable it : directTable) {
				bb.setUInt8(DataType.STRUCTURE.getValue());
				bb.setUInt8(7);
				GXCommon.setData(settings, bb, DataType.INT16, it.getSourceSId());
				GXCommon.setData(settings, bb, DataType.INT16, it.getSourceLnId());
				GXCommon.setData(settings, bb, DataType.INT16, it.getSourceLcId());
				GXCommon.setData(settings, bb, DataType.INT16, it.getDestinationSId());
				GXCommon.setData(settings, bb, DataType.INT16, it.getDestinationLnId());
				GXCommon.setData(settings, bb, DataType.INT16, it.getDestinationLcId());
				GXCommon.setData(settings, bb, DataType.OCTET_STRING, it.getDid());
			}
		}
		return bb.array();
	}

	private byte[] getAvailableSwitches(final GXDLMSSettings settings) {
		GXByteBuffer bb = new GXByteBuffer();
		bb.setUInt8(DataType.ARRAY.getValue());
		if (availableSwitches == null) {
			GXCommon.setObjectCount(0, bb);
		} else {
			GXCommon.setObjectCount(availableSwitches.length, bb);
			for (GXMacAvailableSwitch it : availableSwitches) {
				bb.setUInt8(DataType.STRUCTURE.getValue());
				bb.setUInt8(5);
				GXCommon.setData(settings, bb, DataType.OCTET_STRING, it.getSna());
				GXCommon.setData(settings, bb, DataType.INT16, it.getLsId());
				GXCommon.setData(settings, bb, DataType.INT8, it.getLevel());
				GXCommon.setData(settings, bb, DataType.INT8, it.getRxLevel());
				GXCommon.setData(settings, bb, DataType.INT8, it.getRxSnr());
			}
		}

		return bb.array();
	}

	private byte[] getCommunications(final GXDLMSSettings settings) {
		GXByteBuffer bb = new GXByteBuffer();
		bb.setUInt8(DataType.ARRAY.getValue());
		if (communications == null) {
			GXCommon.setObjectCount(0, bb);
		} else {
			GXCommon.setObjectCount(communications.length, bb);
			for (GXMacPhyCommunication it : communications) {
				bb.setUInt8(DataType.STRUCTURE.getValue());
				bb.setUInt8(9);
				GXCommon.setData(settings, bb, DataType.OCTET_STRING, it.getEui());
				GXCommon.setData(settings, bb, DataType.INT8, it.getTxPower());
				GXCommon.setData(settings, bb, DataType.INT8, it.getTxCoding());
				GXCommon.setData(settings, bb, DataType.INT8, it.getRxCoding());
				GXCommon.setData(settings, bb, DataType.INT8, it.getRxLvl());
				GXCommon.setData(settings, bb, DataType.INT8, it.getSnr());
				GXCommon.setData(settings, bb, DataType.INT8, it.getTxPowerModified());
				GXCommon.setData(settings, bb, DataType.INT8, it.getTxCodingModified());
				GXCommon.setData(settings, bb, DataType.INT8, it.getRxCodingModified());
			}
		}
		return bb.array();
	}

	/*
	 * Returns value of given attribute.
	 */
	@Override
	public final Object getValue(final GXDLMSSettings settings, final ValueEventArgs e) {
		switch (e.getIndex()) {
		case 1:
			return GXCommon.logicalNameToBytes(getLogicalName());
		case 2:
			return getMulticastEntries(settings);
		case 3:
			return getSwitchTable(settings);
		case 4:
			return getDirectTable(settings);
		case 5:
			return getAvailableSwitches(settings);
		case 6:
			return getCommunications(settings);
		default:
			e.setError(ErrorCode.READ_WRITE_DENIED);
			break;
		}
		return null;
	}

	private GXMacMulticastEntry[] setMulticastEntry(final List<?> value) {
		List<GXMacMulticastEntry> data = new ArrayList<GXMacMulticastEntry>();
		if (value != null) {
			for (Object tmp : value) {
				List<?> it = (List<?>) tmp;
				GXMacMulticastEntry v = new GXMacMulticastEntry();
				v.setId(((Number) it.get(0)).byteValue());
				v.setMembers(((Number) it.get(1)).shortValue());
				data.add(v);
			}
		}
		return data.toArray(new GXMacMulticastEntry[data.size()]);
	}

	private short[] setSwitchTable(final List<?> value) {
		List<Short> data = new ArrayList<Short>();
		if (value != null) {
			for (Object it : value) {
				data.add(((Number) it).shortValue());
			}
		}
		return GXCommon.toShortArray(data);
	}

	private GXMacDirectTable[] setDirectTable(final List<?> value) {
		List<GXMacDirectTable> data = new ArrayList<GXMacDirectTable>();
		if (value != null) {
			for (Object tmp : value) {
				List<?> it = (List<?>) tmp;
				GXMacDirectTable v = new GXMacDirectTable();
				v.setSourceSId(((Number) it.get(0)).shortValue());
				v.setSourceLnId(((Number) it.get(1)).shortValue());
				v.setSourceLcId(((Number) it.get(2)).shortValue());
				v.setDestinationSId(((Number) it.get(3)).shortValue());
				v.setDestinationLnId(((Number) it.get(4)).shortValue());
				v.setDestinationLcId(((Number) it.get(5)).shortValue());
				v.setDid((byte[]) it.get(6));
				data.add(v);
			}
		}
		return data.toArray(new GXMacDirectTable[data.size()]);
	}

	private GXMacAvailableSwitch[] setAvailableSwitches(final List<?> value) {
		List<GXMacAvailableSwitch> data = new ArrayList<GXMacAvailableSwitch>();
		if (value != null) {
			for (Object tmp : value) {
				List<?> it = (List<?>) tmp;
				GXMacAvailableSwitch v = new GXMacAvailableSwitch();
				v.setSna((byte[]) it.get(0));
				v.setLsId(((Number) it.get(1)).shortValue());
				v.setLevel(((Number) it.get(2)).byteValue());
				v.setRxLevel(((Number) it.get(3)).byteValue());
				v.setRxSnr(((Number) it.get(4)).byteValue());
				data.add(v);
			}
		}
		return data.toArray(new GXMacAvailableSwitch[data.size()]);
	}

	private GXMacPhyCommunication[] setCommunications(final List<?> value) {
		List<GXMacPhyCommunication> data = new ArrayList<GXMacPhyCommunication>();
		if (value != null) {
			for (Object tmp : value) {
				List<?> it = (List<?>) tmp;
				GXMacPhyCommunication v = new GXMacPhyCommunication();
				v.setEui((byte[]) it.get(0));
				v.setTxPower(((Number) it.get(1)).byteValue());
				v.setTxCoding(((Number) it.get(2)).byteValue());
				v.setRxCoding(((Number) it.get(3)).byteValue());
				v.setRxLvl(((Number) it.get(4)).byteValue());
				v.setSnr(((Number) it.get(5)).byteValue());
				v.setTxPowerModified(((Number) it.get(6)).byteValue());
				v.setTxCodingModified(((Number) it.get(7)).byteValue());
				v.setRxCodingModified(((Number) it.get(8)).byteValue());
				data.add(v);
			}
		}
		return data.toArray(new GXMacPhyCommunication[data.size()]);
	}

	/*
	 * Set value of given attribute.
	 */
	@Override
	public final void setValue(final GXDLMSSettings settings, final ValueEventArgs e) {
		switch (e.getIndex()) {
		case 1:
			setLogicalName(GXCommon.toLogicalName(e.getValue()));
			break;
		case 2:
			multicastEntries = setMulticastEntry((List<?>) e.getValue());
			break;
		case 3:
			switchTable = setSwitchTable((List<?>) e.getValue());
			break;
		case 4:
			directTable = setDirectTable((List<?>) e.getValue());
			break;
		case 5:
			availableSwitches = setAvailableSwitches((List<?>) e.getValue());
			break;
		case 6:
			communications = setCommunications((List<?>) e.getValue());
			break;
		default:
			e.setError(ErrorCode.READ_WRITE_DENIED);
			break;
		}
	}

	private GXMacMulticastEntry[] loadMulticastEntries(GXXmlReader reader) throws XMLStreamException {
		List<GXMacMulticastEntry> list = new ArrayList<GXMacMulticastEntry>();
		if (reader.isStartElement("MulticastEntries", true)) {
			while (reader.isStartElement("Item", true)) {
				GXMacMulticastEntry it = new GXMacMulticastEntry();
				list.add(it);
				it.setId((byte) reader.readElementContentAsInt("Id"));
				it.setMembers((short) reader.readElementContentAsInt("Members"));
			}
			reader.readEndElement("MulticastEntries");
		}
		return list.toArray(new GXMacMulticastEntry[list.size()]);
	}

	private short[] loadSwitchTable(GXXmlReader reader) throws XMLStreamException {
		List<Short> list = new ArrayList<Short>();
		if (reader.isStartElement("SwitchTable", true)) {
			while (reader.isStartElement("Item", false)) {
				list.add((short) reader.readElementContentAsInt("Item"));
			}
			reader.readEndElement("SwitchTable");
		}
		return GXCommon.toShortArray(list);
	}

	private GXMacDirectTable[] loadDirectTable(GXXmlReader reader) throws XMLStreamException {
		List<GXMacDirectTable> list = new ArrayList<GXMacDirectTable>();
		if (reader.isStartElement("DirectTable", true)) {
			while (reader.isStartElement("Item", true)) {
				GXMacDirectTable it = new GXMacDirectTable();
				list.add(it);
				it.setSourceSId((short) reader.readElementContentAsInt("SourceSId"));
				it.setSourceLnId((short) reader.readElementContentAsInt("SourceLnId"));
				it.setSourceLcId((short) reader.readElementContentAsInt("SourceLcId"));
				it.setDestinationSId((short) reader.readElementContentAsInt("DestinationSId"));
				it.setDestinationLnId((short) reader.readElementContentAsInt("DestinationLnId"));
				it.setDestinationLcId((short) reader.readElementContentAsInt("DestinationLcId"));
				it.setDid(GXCommon.hexToBytes(reader.readElementContentAsString("Did")));
			}
			reader.readEndElement("DirectTable");
		}
		return list.toArray(new GXMacDirectTable[list.size()]);
	}

	private GXMacAvailableSwitch[] loadAvailableSwitches(GXXmlReader reader) throws XMLStreamException {
		List<GXMacAvailableSwitch> list = new ArrayList<GXMacAvailableSwitch>();
		if (reader.isStartElement("AvailableSwitches", true)) {
			while (reader.isStartElement("Item", true)) {
				GXMacAvailableSwitch it = new GXMacAvailableSwitch();
				list.add(it);
				it.setSna(GXCommon.hexToBytes(reader.readElementContentAsString("Sna")));
				it.setLsId((short) reader.readElementContentAsInt("LsId"));
				it.setLevel((byte) reader.readElementContentAsInt("Level"));
				it.setRxLevel((byte) reader.readElementContentAsInt("RxLevel"));
				it.setRxSnr((byte) reader.readElementContentAsInt("RxSnr"));
			}
			reader.readEndElement("AvailableSwitches");
		}
		return list.toArray(new GXMacAvailableSwitch[list.size()]);
	}

	private GXMacPhyCommunication[] loadCommunications(GXXmlReader reader) throws XMLStreamException {
		List<GXMacPhyCommunication> list = new ArrayList<GXMacPhyCommunication>();
		if (reader.isStartElement("Communications", true)) {
			while (reader.isStartElement("Item", true)) {
				GXMacPhyCommunication it = new GXMacPhyCommunication();
				list.add(it);
				it.setEui(GXCommon.hexToBytes(reader.readElementContentAsString("Eui")));
				it.setTxPower((byte) reader.readElementContentAsInt("TxPower"));
				it.setTxCoding((byte) reader.readElementContentAsInt("TxCoding"));
				it.setRxCoding((byte) reader.readElementContentAsInt("RxCoding"));
				it.setRxLvl((byte) reader.readElementContentAsInt("RxLvl"));
				it.setSnr((byte) reader.readElementContentAsInt("Snr"));
				it.setTxPowerModified((byte) reader.readElementContentAsInt("TxPowerModified"));
				it.setTxCodingModified((byte) reader.readElementContentAsInt("TxCodingModified"));
				it.setRxCodingModified((byte) reader.readElementContentAsInt("RxCodingModified"));
			}
			reader.readEndElement("Communications");
		}
		return list.toArray(new GXMacPhyCommunication[list.size()]);
	}

	@Override
	public final void load(final GXXmlReader reader) throws XMLStreamException {
		multicastEntries = loadMulticastEntries(reader);
		switchTable = loadSwitchTable(reader);
		directTable = loadDirectTable(reader);
		availableSwitches = loadAvailableSwitches(reader);
		communications = loadCommunications(reader);
	}

	private void saveMulticastEntries(GXXmlWriter writer) throws XMLStreamException {
		writer.writeStartElement("MulticastEntries");
		if (multicastEntries != null) {
			for (GXMacMulticastEntry it : multicastEntries) {
				writer.writeStartElement("Item");
				writer.writeElementString("Id", it.getId());
				writer.writeElementString("Members", it.getMembers());
				writer.writeEndElement();
			}
		}
		writer.writeEndElement();
	}

	private void saveSwitchTable(GXXmlWriter writer) throws XMLStreamException {
		writer.writeStartElement("SwitchTable");
		if (switchTable != null) {
			for (short it : switchTable) {
				writer.writeElementString("Item", it);
			}
		}
		writer.writeEndElement();
	}

	private void saveDirectTable(GXXmlWriter writer) throws XMLStreamException {
		writer.writeStartElement("DirectTable");
		if (directTable != null) {
			for (GXMacDirectTable it : directTable) {
				writer.writeStartElement("Item");
				writer.writeElementString("SourceSId", it.getSourceSId());
				writer.writeElementString("SourceLnId", it.getSourceLnId());
				writer.writeElementString("SourceLcId", it.getSourceLcId());
				writer.writeElementString("DestinationSId", it.getDestinationSId());
				writer.writeElementString("DestinationLnId", it.getDestinationLnId());
				writer.writeElementString("DestinationLcId", it.getDestinationLcId());
				writer.writeElementString("Did", GXCommon.toHex(it.getDid(), false));
				writer.writeEndElement();
			}
		}
		writer.writeEndElement();
	}

	private void saveAvailableSwitches(GXXmlWriter writer) throws XMLStreamException {
		writer.writeStartElement("AvailableSwitches");
		if (availableSwitches != null) {
			for (GXMacAvailableSwitch it : availableSwitches) {
				writer.writeStartElement("Item");
				writer.writeElementString("Sna", GXCommon.toHex(it.getSna(), false));
				writer.writeElementString("LsId", it.getLsId());
				writer.writeElementString("Level", it.getLevel());
				writer.writeElementString("RxLevel", it.getRxLevel());
				writer.writeElementString("RxSnr", it.getRxSnr());
				writer.writeEndElement();
			}
		}
		writer.writeEndElement();
	}

	private void saveCommunications(GXXmlWriter writer) throws XMLStreamException {
		writer.writeStartElement("Communications");
		if (communications != null) {
			for (GXMacPhyCommunication it : communications) {
				writer.writeStartElement("Item");
				writer.writeElementString("Eui", GXCommon.toHex(it.getEui(), false));
				writer.writeElementString("TxPower", it.getTxPower());
				writer.writeElementString("TxCoding", it.getTxCoding());
				writer.writeElementString("RxCoding", it.getRxCoding());
				writer.writeElementString("RxLvl", it.getRxLvl());
				writer.writeElementString("Snr", it.getSnr());
				writer.writeElementString("TxPowerModified", it.getTxPowerModified());
				writer.writeElementString("TxCodingModified", it.getTxCodingModified());
				writer.writeElementString("RxCodingModified", it.getRxCodingModified());
				writer.writeEndElement();
			}
		}
		writer.writeEndElement();
	}

	@Override
	public final void save(final GXXmlWriter writer) throws XMLStreamException {
		saveMulticastEntries(writer);
		saveSwitchTable(writer);
		saveDirectTable(writer);
		saveAvailableSwitches(writer);
		saveCommunications(writer);
	}

	@Override
	public final void postLoad(final GXXmlReader reader) {
	}

	@Override
	public String[] getNames() {
		return new String[] { "Logical Name", "MulticastEntries", "SwitchTable", "DirectTable", "AvailableSwitches",
				"Communications" };

	}

	@Override
	public String[] getMethodNames() {
		return new String[] { "Reset" };
	}
}